<script setup lang="ts">
import { getBody, vmboxApi } from "@/api/Api";
import SpiceComponents from "@/components/SpiceComponents.vue";
import VncComponents from "@/components/VncComponents.vue";
import CreateHostComponent from "@/components/CreateHostComponent.vue";
import styles from "@/style/styles";
import { fullScreen, fullScreenExit } from 'gtl-utils/utils/html-utils';

import {
  Folder,
  FolderAdd,
  FolderRemove,
  Location,
  Monitor,
  Plus,
  Setting,
  SwitchButton,
} from "@element-plus/icons-vue";
import { ElMessageBox } from "element-plus";
import { onMounted, ref, onBeforeUnmount } from "vue";
import { BIconFullscreen } from "bootstrap-icons-vue";

/** 远程显示信息 */
const fullScreen = ref(false);
const display = ref("");
const url = ref("");
const passwd = ref("");

const onMoveHost = ref("");
const delDir = ref(false);
const addDir = ref(false);
const createVirtHost = ref(false)
const dir = ref("");
const vmboxHost = ref<Array<VmboxHostList>>([]);
const form = ref({ disk: [1, 2, 3], name: "default", region: "x" });

const fullScreenChange = (e: Event) => {
  fullScreen.value = false;
  document.addEventListener("fullscreenchange", fullScreenChange);
}

const setFullScreen = () => {
  fullScreen.value ? fullScreenExit() : fullScreen();
  fullScreen.value = !fullScreen.value;
  document.addEventListener("fullscreenchange", fullScreenChange);
}

onMounted(() => {
  console.log("info");
  getHosts();
  document.addEventListener("fullscreenchange", fullScreenChange);
});

onBeforeUnmount(() => {
  document.removeEventListener("fullscreenchange", fullScreenChange);
})

interface VmboxHostList {
  name: string;
  isDir: boolean;
  index: string;
  child?: Array<VmboxHostList>;
  isActive?: boolean;
  parent?: VmboxHostList;
  protocol?: string;
  cpus?: number;
  memory?: number;
}

const getHosts = () => {
  vmboxHost.value.length = 0;
  vmboxApi.getHosts({
    success: (vmbox: VmboxHostList[]) => {
      vmbox.forEach((vhost) => {
        vmboxHost.value.push(vhost);
      });
    },
  });
};

const handleOpen = () => { };

const handleClose = () => { };

const doubleCli = (e: any) => {
  console.log(e);
  e.preventDefault();
};

const deleteDir = () => {
  vmboxApi.delDir({
    body: getBody().set("id", dir.value).toFormData(),
    success: (data: JSON) => {
      alert(JSON.stringify(data));
      getHosts();
    },
  });
  dir.value = "";
  delDir.value = false;
};

const createDir = (e: any) => {
  /** 新建目录 */
  vmboxApi.addDir({
    body: getBody().set("name", dir.value).set("sort", "1").toFormData(),
    success: (data: JSON) => {
      alert(JSON.stringify(data));
      getHosts();
    },
    fail: (err: any) => {
      alert(err);
    },
  });

  addDir.value = false;
};

const hostButton = (e: any, host: any, protocol: any) => {
  url.value = host;
  display.value = protocol;
};

const vmShutdown = (e: any, uuid: any) => {
  ElMessageBox.confirm("取消正常关机?", "提示", {
    confirmButtonText: "强制关机",
    cancelButtonText: "正常关机",
  })
    .then((e: any) => {
      vmboxApi.destroy({
        body: getBody().set("uuid", uuid).toFormData(),
        success: (data: any) => {
          console.log(data);
        },
        fail: (data: any) => {
          console.log(data);
        },
      });
    })
    .catch((e: any) => {
      console.log(e);

      vmboxApi.shutdown({
        body: getBody().set("uuid", uuid).toFormData(),
        success: (data: any) => {
          console.log(data);
        },
        fail: (data: any) => {
          console.log(data);
        },
      });
    });
};

const vmStart = (e: any, uuid: any) => {
  vmboxApi.start({
    body: getBody().set("uuid", uuid).toFormData(),
    success: (data: any) => {
      if (data["status"] != "ok") {
        alert(data["msg"]);
      }
      console.log(data);
    },
    fail: (data: any) => {
      console.log(data);
    },
  });
};

const vmDestroy = (e: any, uuid: any) => {
  vmboxApi.start({
    body: getBody().set("uuid", uuid).toFormData(),
    success: (data: any) => {
      console.log(data);
    },
    fail: (data: any) => {
      console.log(data);
    },
  });
};

const xml = ref("");

const vmSetting = (e: any, uuid: any) => {
  display.value = "hostXml";
  vmboxApi.getXml({
    body: getBody().set("uuid", uuid).toFormData(),
    success: (data: any) => {
      let parser = new DOMParser();
      let xmlDoc = parser.parseFromString(data.data, "text/xml");
      let root = document.createElement("root");
      root.append(xmlDoc.documentElement);
      console.log(root);
      xml.value = root.innerText;
    },
    fail: (data: any) => { },
  });
};

const hostMove = (e: MouseEvent) => {
  let time = new Date().getTime();
  let stat = { status: true };
  let st: any;
  let getNode = (e: any) => {
    if (e.tagName != "LI") {
      getNode(e.parentNode);
    } else {
      st = e.cloneNode(true);
      st.style.width = "320px";
    }
  };
  getNode(e.target);
  setTimeout(() => {
    if (stat["status"]) {
      st.remove();
      st.style.backgroundColor = "rgba(91, 91, 91, 0.413)";
      st.style.position = "absolute";
      st.style.left = e.pageX + 10 + "px";
      st.style.top = e.pageY + 10 + "px";
      document.getElementsByTagName("body")[0].appendChild(st);
      onMoveHost.value = "no-drop";
    }
  }, 600);

  function onmove(e: MouseEvent) {
    st.style.left = e.pageX + 10 + "px";
    st.style.top = e.pageY + 10 + "px";
  }

  /**递归获取目录节点*/
  const getDirId = (node: any, depth: number): string | null => {
    if (depth < 0 || node == undefined) {
      return null;
    }
    return node?.nodeName == "LI" ? node.id : getDirId(node?.parentNode, depth - 1);
  };

  const mouseUp = (e: MouseEvent) => {
    let dirId = getDirId(e.target, 4);
    if (
      dirId != null &&
      (dirId == parseInt(dirId).toString() || dirId == "default-org")
    ) {
      let uuid = st.id;
      vmboxApi.moveHost({
        body: getBody().set("id", dirId).set("uuid", uuid).toFormData(),
        success: (data: any) => {
          getHosts();
        },
        fail: (err: any) => {
          alert(JSON.stringify(err));
        },
      });
    }
    stat["status"] = false;
    window.removeEventListener("mousemove", onmove);
    st.remove();
    window.removeEventListener("mouseup", mouseUp);
    onMoveHost.value = "";
  };
  window.addEventListener("mousemove", onmove);
  window.addEventListener("mouseup", mouseUp);
};
const moveMouseLeave = () => {
  var mouseEvent = new MouseEvent("mouseup", {
    view: window,
    bubbles: true,
    cancelable: true,
    clientX: 0,
    clientY: 0,
  });

  var element = document.getElementById("app");
  element!.dispatchEvent(mouseEvent);
};
</script>

<template>
  <el-menu @contextmenu="doubleCli" default-active="2" class="el-menu-vertical-demo" @open="handleOpen"
    @close="handleClose" @mouseleave="moveMouseLeave" :style="{
      width: 'var(--left-bar-width)',
      height: 'var(--ingres-top-bar)',
      userSelect: 'none',
      cursor: onMoveHost,
    }">
    <template #title>
      <el-icon>
        <location />
      </el-icon>
      <span>vmbox</span>
    </template>
    <el-menu-item id="vmbox-config" :style="{ cursor: onMoveHost }">
      <el-button title="创建虚拟机" @click="createVirtHost = true">
        <el-icon style="text-align: center" :style="{ cursor: onMoveHost }">
          <Plus />
        </el-icon>
      </el-button>
      <el-button title="添加目录" @click="addDir = true" :style="{ cursor: onMoveHost }">
        <el-icon>
          <FolderAdd />
        </el-icon>
      </el-button>
      <el-button title="删除目录" @click="delDir = true" :style="{ cursor: onMoveHost }">
        <el-icon>
          <FolderRemove />
        </el-icon>
      </el-button>
      <el-button title="设置" :style="{ cursor: onMoveHost }">
        <el-icon>
          <Setting />
        </el-icon>
      </el-button>
    </el-menu-item>

    <el-sub-menu v-for="(v, i) in vmboxHost" :index="v.index" :id="v.index">
      <template #title style="user-select: none">
        <el-icon>
          <Folder />
        </el-icon>
        <span>{{ v.name }}</span>
      </template>
      <el-menu-item v-for="(val, index) in v.child" :index="val.index" style="height: 80px; padding-right: 0px"
        :id="val.index" @mousedown="hostMove($event)" :style="{ cursor: onMoveHost }">
        <el-icon style="font-size: 86px; width: 55px">
          <Monitor v-if="val.isActive" style="color: green" />
          <Monitor v-if="!val.isActive" style="color: black" />
        </el-icon>
        <div style="height: 100%; width: 70%">
          <span style="display: block; height: 16px">{{ val.name }}</span>
          <span style="display: block; height: 16px">处理器: {{ val.cpus }}核</span>
          <span style="display: block; height: 16px">
            内存: {{ (val.memory == null ? 0 : val.memory) / 1024 / 1024 }}G
          </span>
        </div>
        <div style="height: 100%; width: 30%">
          <div style="height: 35px; width: 30%">
            <!-- 开关机 -->
            <el-button circle style="
                width: 20px;
                height: 20px;
                margin-left: 0px;
                padding: 12px 12px 12px 12px;
              " @click="
                val.isActive ? vmShutdown($event, val.index) : vmStart($event, val.index)
                ">
              <el-icon v-if="val.isActive" style="font-size: 20px; margin-left: 4px; color: green" title="关机">
                <SwitchButton />
              </el-icon>
              <el-icon v-if="!val.isActive" style="font-size: 20px; margin-left: 4px" title="开机">
                <SwitchButton />
              </el-icon>
            </el-button>

            <!-- 设置按钮 -->
            <el-button circle style="
                width: 20px;
                height: 20px;
                margin-left: 0px;
                padding: 12px 12px 12px 12px;
              " @click="vmSetting($event, val.index)">
              <el-icon style="font-size: 20px; margin-left: 4px" title="设置">
                <Setting />
              </el-icon>
            </el-button>

            <!-- 桌面 -->
            <el-button v-if="val.isActive" circle style="
                width: 20px;
                height: 20px;
                margin-left: 0px;
                padding: 12px 12px 12px 12px;
              " @click="hostButton($event, val.index, val.protocol)">
              <el-icon style="font-size: 20px; margin-left: 4px">
                <Monitor />
              </el-icon>
            </el-button>
          </div>
        </div>
      </el-menu-item>
    </el-sub-menu>
  </el-menu>

  <!-- 分组操作提示框 -->
  <el-dialog v-model="delDir" title="删除分组" width="350" align-center style="text-align: center">
    <div style="width: 100%; text-align: center">
      <img id="user-icon" style="background-image: url('/favicon.ico')" />
      <div style="margin-bottom: 25px">
        <span style="color: red">删除分组! 机器将被移动到未分组</span>
      </div>
      <div style="margin-bottom: 25px">
        <label style="margin-right: 9px">分组: </label>
        <el-select v-model="dir" placeholder="Select" size="large" style="width: 240px">
          <el-option v-for="item in vmboxHost.filter((d) => d.index != 'default-org' || !d.isDir)" :key="item.index"
            :label="item.name" :value="item.index" />
        </el-select>
      </div>
      <el-button type="primary" @click="deleteDir">确认删除</el-button>
      <el-button type="danger" @click="delDir = false">取消</el-button>
    </div>
  </el-dialog>

  <!-- 创建分组会话框 -->
  <el-dialog v-model="addDir" title="新建分组" width="350" align-center
    :style="{ textAlign: 'center', cursor: onMoveHost }">
    <div style="width: 100%; text-align: center">
      <img id="user-icon" style="background-image: url('/favicon.ico')" />
      <div style="margin-bottom: 25px">
        <label style="margin-right: 9px">新建分组: </label>
        <el-input v-model="dir" style="width: 240px" placeholder="新建分组名" />
      </div>
      <el-button type="primary" @click="createDir">确认</el-button>
      <el-button type="danger" @click="addDir = false">取消</el-button>
    </div>
  </el-dialog>

  <!-- 新建虚拟机窗口  -->
  <el-dialog v-model="createVirtHost" title="创建虚拟机" width="820" align-center
    :style="{ textAlign: 'center', cursor: onMoveHost }">
    <div style="width: 100%; height: 500px; text-align: center">
      <CreateHostComponent v-if="createVirtHost"></CreateHostComponent>
    </div>
  </el-dialog>

  <!-- 显示 -->
  <div :style="fullScreen
      ? {
        width: '100% ',
        height: '100%',
        position: 'absolute',
        top: '0px',
        left: '0px',
        backgroundColor: 'rgba(108, 108, 108, 0.598)',
        borderRadius: '6px',
        zIndex: 1,
        overflow: 'hidden',
        ...styles.flexCenter,
      }
      : {
        width: 'calc( 100% - 329px )',
        height: 'calc( 100% - 70px )',
        position: 'absolute',
        top: '65px',
        right: '5px',
        backgroundColor: 'rgba(108, 108, 108, 0.598)',
        borderRadius: '6px',
        zIndex: 1,
        overflow: 'hidden',
        ...styles.flexCenter,
      }
    ">
    <template v-if="display == ''"> </template>
    <template v-if="display == 'hostXml'">
      <el-form :model="form">
        <el-form-item label="设备名">
          <el-input v-model="form.name" />
        </el-form-item>

        <el-form-item v-for="i in form.disk" label="设备名">
          <el-input v-model="form.name" :value="i" />
        </el-form-item>

        <el-form-item label="选择设备">
          <el-select v-model="form.region" placeholder="please select your zone">
            <el-option label="Zone one" value="shanghai" />
            <el-option label="Zone two" value="beijing" />
          </el-select>
        </el-form-item>
      </el-form>
    </template>

    <template v-if="display == 'vnc'">
      <div :style="{ overflow:  'auto', width: '100%', height: '100%' , ...styles.flexCenter}">
        <VncComponents :url="url" :password="passwd"></VncComponents>
      </div>
    </template>
    <template v-if="display == 'spice'">
      <div :style="{ overflow: 'auto', width: '100%', height: '100%', ...styles.flexCenter }">
        <SpiceComponents :url="url" :passwd="passwd"></SpiceComponents>
      </div>
    </template>

    <template v-if="display != ''">
      <div :style="{
        width: '13px',
        height: '13px',
        borderRadius: '2px',
        position: 'absolute',
        backgroundColor: 'rgba(255, 255, 255, 0.629)',
        right: '1px',
        bottom: '1px',
        zIndex: 2,
        padding: '5px 5px',
        lineHeight: '13px'
      }" @click="setFullScreen">
        <BIconFullscreen style="color: rgb(35, 167, 211); font-size: 13px" />
      </div>
    </template>
  </div>
</template>

<style>
:root {
  --left-bar-width: 320px;
}
</style>
<style scoped>
#vmbox-config:hover {
  background-color: white;
}
</style>
